#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
NVMe写入性能测试结果可视化工具 - 无字体问题版本
专门解决中文字体显示问题
"""

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import numpy as np
import re
import sys
from datetime import datetime

# 强制使用英文，避免中文字体问题
plt.rcParams['font.family'] = 'DejaVu Sans'
plt.rcParams['axes.unicode_minus'] = False

class NVMeTestVisualizerSafe:
    def __init__(self, log_file_path):
        self.log_file_path = log_file_path
        self.test_config = {}
        self.test_data = []
        self.summary = {}

    def parse_log_file(self):
        """解析日志文件"""
        try:
            with open(self.log_file_path, 'r', encoding='utf-8') as f:
                content = f.read()
        except UnicodeDecodeError:
            with open(self.log_file_path, 'r', encoding='gbk') as f:
                content = f.read()

        self._parse_config(content)
        self._parse_test_data(content)
        self._parse_summary(content)

    def _parse_config(self, content):
        """解析测试配置"""
        config_patterns = {
            'path': r'测试路径:\s*(.+)',
            'block_size': r'块大小:\s*(\d+)\s*KB',
            'file_size': r'目标文件大小:\s*([\d.]+)\s*(\w+)',
            'direct_io': r'DirectIO:\s*(.+)',
            'sync_io': r'SyncIO:\s*(.+)',
            'report_interval': r'报告间隔:\s*(\d+)\s*MB'
        }

        for key, pattern in config_patterns.items():
            match = re.search(pattern, content)
            if match:
                if key == 'file_size':
                    self.test_config[key] = f"{match.group(1)} {match.group(2)}"
                else:
                    self.test_config[key] = match.group(1)

    def _parse_test_data(self, content):
        """解析测试数据"""
        data_pattern = r'(\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(.+)'

        lines = content.split('\n')
        for line in lines:
            match = re.match(data_pattern, line.strip())
            if match:
                written_mb = int(match.group(1))
                progress = float(match.group(2))
                instant_speed = float(match.group(3))
                avg_speed = float(match.group(4))
                eta = match.group(5).strip()

                self.test_data.append({
                    'written_mb': written_mb,
                    'progress': progress,
                    'instant_speed': instant_speed,
                    'avg_speed': avg_speed,
                    'eta': eta
                })

    def _parse_summary(self, content):
        """解析测试总结"""
        summary_patterns = {
            'target_size': r'目标文件大小:\s*([\d.]+\s*\w+)',
            'actual_size': r'实际写入大小:\s*([\d.]+)\s*MB',
            'progress': r'完成进度:\s*([\d.]+)%',
            'total_time': r'总耗时:\s*([\d.]+)\s*秒',
            'avg_speed': r'平均写入速度:\s*([\d.]+)\s*MB/s'
        }

        for key, pattern in summary_patterns.items():
            match = re.search(pattern, content)
            if match:
                self.summary[key] = match.group(1)

    def create_visualizations(self):
        """创建可视化图表"""
        if not self.test_data:
            print("Error: No test data found")
            return

        # 创建子图
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
        fig.suptitle('NVMe Storage Performance Test Analysis', fontsize=16, fontweight='bold')

        # 提取数据
        written_data = [d['written_mb'] for d in self.test_data]
        progress_data = [d['progress'] for d in self.test_data]
        instant_speed_data = [d['instant_speed'] for d in self.test_data]
        avg_speed_data = [d['avg_speed'] for d in self.test_data]

        # 图1: 写入进度曲线
        ax1.plot(written_data, progress_data, 'b-', linewidth=2, label='Write Progress')
        ax1.set_xlabel('Data Written (MB)')
        ax1.set_ylabel('Progress (%)')
        ax1.set_title('Write Progress Curve')
        ax1.grid(True, alpha=0.3)
        ax1.legend()

        # 图2: 速度变化
        ax2.plot(written_data, instant_speed_data, 'r-', alpha=0.7, label='Instant Speed')
        ax2.plot(written_data, avg_speed_data, 'g--', linewidth=2, label='Average Speed')
        ax2.set_xlabel('Data Written (MB)')
        ax2.set_ylabel('Write Speed (MB/s)')
        ax2.set_title('Write Speed Variation')
        ax2.grid(True, alpha=0.3)
        ax2.legend()

        # 图3: 速度分布直方图
        ax3.hist(instant_speed_data, bins=20, alpha=0.7, color='orange', edgecolor='black')
        ax3.axvline(np.mean(instant_speed_data), color='red', linestyle='--',
                    label=f'Mean: {np.mean(instant_speed_data):.1f} MB/s')
        ax3.set_xlabel('Instantaneous Write Speed (MB/s)')
        ax3.set_ylabel('Frequency')
        ax3.set_title('Speed Distribution')
        ax3.legend()
        ax3.grid(True, alpha=0.3)

        # 图4: 统计信息
        ax4.axis('off')
        stats_text = self._generate_stats_text(instant_speed_data, avg_speed_data)
        ax4.text(0.05, 0.95, stats_text, transform=ax4.transAxes, fontsize=10,
                 verticalalignment='top', fontfamily='monospace',
                 bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.7))

        plt.tight_layout()

        # 保存图表
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f'nvme_analysis_safe_{timestamp}.png'
        plt.savefig(filename, dpi=300, bbox_inches='tight')
        print(f"Chart saved as: {filename}")

        plt.show()

    def _generate_stats_text(self, instant_speeds, avg_speeds):
        """生成统计信息文本（英文版）"""
        stats_lines = [
            "=== PERFORMANCE STATISTICS ===",
            f"Max Speed:    {max(instant_speeds):.2f} MB/s",
            f"Min Speed:    {min(instant_speeds):.2f} MB/s",
            f"Mean Speed:   {np.mean(instant_speeds):.2f} MB/s",
            f"Std Dev:      {np.std(instant_speeds):.2f} MB/s",
            f"Stability:    {((1 - np.std(instant_speeds)/np.mean(instant_speeds)) * 100):.1f}%",
            "",
            "=== TEST CONFIGURATION ===",
            f"Path:         {self.test_config.get('path', 'N/A')}",
            f"Block Size:   {self.test_config.get('block_size', 'N/A')} KB",
            f"Target Size:  {self.test_config.get('file_size', 'N/A')}",
            f"DirectIO:     {self.test_config.get('direct_io', 'N/A')}",
            "",
            "=== TEST RESULTS ===",
            f"Duration:     {self.summary.get('total_time', 'N/A')} sec",
            f"Avg Speed:    {self.summary.get('avg_speed', 'N/A')} MB/s",
            f"Data Size:    {self.summary.get('actual_size', 'N/A')} MB",
            f"Progress:     {self.summary.get('progress', 'N/A')}%"
        ]

        return '\n'.join(stats_lines)

    def print_analysis(self):
        """打印分析结果"""
        if not self.test_data:
            print("Error: No test data found")
            return

        instant_speeds = [d['instant_speed'] for d in self.test_data]

        print("=" * 60)
        print("NVMe Storage Performance Test Analysis Report")
        print("=" * 60)

        print(f"\n📊 Test Overview:")
        print(f"   Test Path: {self.test_config.get('path', 'N/A')}")
        print(f"   Target Size: {self.test_config.get('file_size', 'N/A')}")
        print(f"   Block Size: {self.test_config.get('block_size', 'N/A')} KB")
        print(f"   DirectIO: {self.test_config.get('direct_io', 'N/A')}")

        print(f"\n⚡ Performance Metrics:")
        print(f"   Max Instant Speed: {max(instant_speeds):.2f} MB/s")
        print(f"   Min Instant Speed: {min(instant_speeds):.2f} MB/s")
        print(f"   Mean Instant Speed: {np.mean(instant_speeds):.2f} MB/s")
        print(f"   Speed Std Dev: {np.std(instant_speeds):.2f} MB/s")
        print(f"   Speed Stability: {((1 - np.std(instant_speeds)/np.mean(instant_speeds)) * 100):.1f}%")

        print(f"\n📈 Test Results:")
        print(f"   Total Duration: {self.summary.get('total_time', 'N/A')} seconds")
        print(f"   Data Written: {self.summary.get('actual_size', 'N/A')} MB")
        print(f"   Average Speed: {self.summary.get('avg_speed', 'N/A')} MB/s")
        print(f"   Completion: {self.summary.get('progress', 'N/A')}%")

        # 性能评级
        avg_speed = float(self.summary.get('avg_speed', '0'))
        performance_grade = self._get_performance_grade(avg_speed)
        print(f"\n🏆 Performance Grade: {performance_grade}")

        print("=" * 60)

    def _get_performance_grade(self, speed):
        """性能评级"""
        if speed >= 1000:
            return "Excellent (High-end NVMe SSD)"
        elif speed >= 500:
            return "Good (Mid-high end SSD)"
        elif speed >= 300:
            return "Average (Regular SATA SSD)"
        elif speed >= 100:
            return "Fair (Entry-level SSD/HDD)"
        else:
            return "Poor (Check configuration)"

def main():
    print("NVMe Test Result Visualizer (Font-Safe Version)")
    print("=" * 50)

    # 获取日志文件路径
    if len(sys.argv) > 1:
        log_file = sys.argv[1]
    else:
        log_file = input("Enter log file path (default: Documents.txt): ").strip()
        if not log_file:
            log_file = "Documents.txt"

    try:
        # 创建可视化器
        visualizer = NVMeTestVisualizerSafe(log_file)

        # 解析日志文件
        print(f"Parsing log file: {log_file}")
        visualizer.parse_log_file()

        # 打印分析结果
        visualizer.print_analysis()

        # 创建可视化图表
        print("\nGenerating visualization charts...")
        visualizer.create_visualizations()

    except FileNotFoundError:
        print(f"Error: Log file '{log_file}' not found")
        print("Please check the file path")
    except Exception as e:
        print(f"Error: {str(e)}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()